#include <iostream>
#include <thread>
#include <functional>
#include <vector>
#include <mutex>
#include <string>
#include "prod.hpp"

using namespace std;


template <class T>
class ThreadPool
{
    static const u_int32_t default_num = 5;  // 默认线程个数
    static const u_int32_t default_cap = 10; // 默认生产者消费者模型的环形队列的最大容量

    bool isRunning()
    {
        lock_guard<mutex> m(_mutex); // 锁,保护isrunning
        return _isrunning == true;
    }

    void PerfTask(const string &name)//获取并执行任务
    {
        while (true)
        {
            T task;
            if (_rq.isEmpty()) // 如果阻塞队列为空
            {
                if (!isRunning()) // 如果线程池  没有运行
                {
                    cout << name << "退出" << endl;
                    return; // 线程退出
                }
            }

            cout << name << "去获取任务....." << endl;
            bool rval=_rq.Pop(task); // 从阻塞队列里面拿任务
            if(rval)
            {
                cout << name << "任务获取成功" << endl;
                task(); // 执行任务
            }
            else
            {
                cout << name << "任务获取失败" << endl;
            }
        }
    }

    ThreadPool(u_int32_t thread_num = default_num, u_int32_t cap = default_cap)
        : _thread_num(thread_num),
          _isrunning(false),
          _rq(cap)
    {
    }
    ThreadPool(const ThreadPool<T>&obj)=delete;
    ThreadPool<T>& operator=(const ThreadPool<T>&obj)=delete;

public:
    static ThreadPool<T>* GetInstance(u_int32_t thread_num = default_num, u_int32_t cap = default_cap)
    {
        if(_This==nullptr)
        {
            lock_guard<mutex> m(_mutex); // 锁,保护_This

            _This=new ThreadPool<T>(thread_num,cap);
        }
        return _This;     
    }
    
    bool Start()
    {
        _rq.CancelExternalSignal();//取消外部唤醒状态

        {
            lock_guard<mutex> m(_mutex); // 锁,保护isruning
            if (_isrunning == true)          // 不许重复启动
            {
                return false;
            }
            _isrunning = true;
            cout << "启动线程池" << endl;
        }

        for (int i = 0; i < _thread_num; i++) // 创建_thread_num个执行任务的线程
        {
            string s = "线程";
            s += to_string(i + 1);
            _threads.emplace_back([this](const string &name)
                                  { this->PerfTask(name); }, s); // 线程去PerfTask中等待任务

            cout << "创建线程" << i + 1 << "成功" << endl;
        }

        return true;
    }
    void Wait()//回收线程
    {
        for(auto &t:_threads)
        {
            t.join();
        }
        _threads.clear();//清除线程对象
    }

    bool Stop()
    {
        lock_guard<mutex> m(_mutex); // 锁,保护isruning
        _isrunning = false;
        _rq.ExternalSignal();//外部唤醒  阻塞队列中的  阻塞等待的线程

        cout << "关闭线程池" << endl<< endl<< endl;
        return true;
    }
    bool PushTask(const T &task)
    {
        if (isRunning()) // 线程池运行才能生产
        {
            _rq.Push(task); // 生产任务
            cout << "主线程生产任务" << endl;
        }
        else
        {
            return false;
        }
        return true;
    }

private:
    static ThreadPool<T>* _This;

    u_int32_t _thread_num; // 线程总个数
    BlocQueue<T> _rq;      // 基于阻塞队列的生产者消费者模型
    bool _isrunning;       // 是否运行
    static mutex _mutex;      // 锁,保护_isruning

    vector<thread> _threads; // 管理线程
};

template<class T>
ThreadPool<T>* ThreadPool<T>::_This=nullptr;

template<class T>
mutex ThreadPool<T>::_mutex;
